package repositories

import (
	"context"
	"github.com/pkg/errors"
	"go.didapinche.com/foundation/plat-echo/app/ops/models"
	"gorm.io/gorm"
)

type TempTypeRepository interface {
	Create(ctx context.Context, tempType *models.TempType) error
	Delete(ctx context.Context, id uint64) error
	Find(ctx context.Context) ([]*models.TempType, error)
	FindAll(ctx context.Context) ([]*models.TempType, error)
	FindByKey(ctx context.Context, key string) (*models.TempType, error)
	FindByID(ctx context.Context, ID uint64) (*models.TempType, error)
	Update(ctx context.Context, tempType *models.TempType) error
	FindByTemplateType(ctx context.Context, templateType models.TypeEnum) ([]*models.TempType, error)
	FindByTypeID(ctx context.Context, ID uint64) (int64, error)
}

type tempTypeRepository struct {
	db *gorm.DB
}

func NewTempTypeRepository(db *gorm.DB) TempTypeRepository {
	return &tempTypeRepository{
		db: db,
	}
}

func (r *tempTypeRepository) FindAll(ctx context.Context) (types []*models.TempType, err error) {
	if err := r.db.WithContext(ctx).Table(models.TempTypeTableName).Order("`order` asc").Find(&types).Error; err != nil {
		return nil, errors.Wrap(err, "find all tempType err")
	}
	return
}

func (r tempTypeRepository) Create(ctx context.Context, tempType *models.TempType) error {
	if err := r.db.WithContext(ctx).Create(tempType).Error; err != nil {
		return errors.Wrap(err, "create subscribe error")
	}
	return nil
}

func (r tempTypeRepository) Delete(ctx context.Context, id uint64) error {
	if err := r.db.WithContext(ctx).Table(models.TempTypeTableName).Delete(models.TempType{}, "id = ?", id).Error; err != nil {
		return errors.Wrap(err, "delete subscribe error")
	}
	return nil
}

func (r tempTypeRepository) Find(ctx context.Context) ([]*models.TempType, error) {
	panic("implement me")
}

func (r *tempTypeRepository) FindByKey(ctx context.Context, key string) (*models.TempType, error) {
	var tempType = new(models.TempType)
	if err := r.db.WithContext(ctx).Table(models.TempTypeTableName).Where("`key` = ?", key).First(&tempType).Error; err != nil {
		return nil, errors.Wrap(err, "find tempType key error")
	}
	return tempType, nil
}

func (r *tempTypeRepository) FindByID(ctx context.Context, ID uint64) (*models.TempType, error) {
	var tempType = new(models.TempType)
	if err := r.db.WithContext(ctx).Table(models.TempTypeTableName).Where("id = ?", ID).First(&tempType).Error; err != nil {
		return nil, errors.Wrap(err, "find tempType id err")
	}
	return tempType, nil
}

func (r *tempTypeRepository) Update(ctx context.Context, tempType *models.TempType) error {
	if err := r.db.WithContext(ctx).Table(models.TempTypeTableName).Save(tempType).Error; err != nil {
		return errors.Wrap(err, "update tempType err")
	}
	return nil
}

func (r *tempTypeRepository) FindByTemplateType(ctx context.Context, templateType models.TypeEnum) (types []*models.TempType, err error) {
	if err := r.db.WithContext(ctx).Table(models.TempTypeTableName).
		Where("template_type = ?", templateType).
		Order("`order` asc").
		Find(&types).Error; err != nil {
		return nil, errors.Wrap(err, "find tempType by templateType err")
	}
	return
}

func (r *tempTypeRepository) FindByTypeID(ctx context.Context, ID uint64) (int64, error) {
	var count int64
	if err := r.db.Table(models.TemplateTableName).
		Where("type_id = ?", ID).
		Count(&count).Error; err != nil {
		return 0, errors.Wrap(err, "find count by templateType err")
	}
	return count, nil
}
